<template>
	 <div class="imgUploadBox" style="overflow:hidden;">
        <div class="imgItem"
            v-for="(item, index) in getFileArray" :key="index">
            <!-- 删除按钮 -->
            <span class="delete-btn" title="删除" @click="deleteImg(index)">×</span>
            <img :src="item" ref="imgItem" />
        </div>
        <div class="upload-btn" v-show="getFileArray.length !== maxCount" ref="getHeight">
            <input type="file" @change="chooseImg" accept="image/gif, image/jpeg, image/png"/>
            <!-- <img src="static/image/suneee-btn.png" /> -->
            <span class="hengxian"></span>
            <span class="shuxian"></span>
        </div>
        <div ref="gwImgCover" class="gw-img-cover" v-show="coverShow" @click.stop="hideCover" :style="{'height': pageHeight + 'px', 'width': pageWidth + 'px'}">
            <div class="cover" :style="{'height': pageHeight + 'px', 'width': pageWidth + 'px'}"></div>
            <img :src="coverSrc" />
        </div>
        <div class="canvasBox">
            <img src="" ref="tempImg" />
            <canvas ref="canvas" background="background: red;"></canvas>
        </div>
        <!-- <div @click="mUpload">上传</div> -->
	</div>
</template>
<script>
    import {uploadImg} from "./uploadImg";
    import { MessageBox } from '../../ui-components';
    import {Toast} from "../../utils/toast";
    import {showLoading, hideLoading} from "../../utils/loading";
	export default {
		props: {
            toast: {
                type: Boolean,
                default: false
            },
            loading: {
                type: Boolean,
                default: true
            },
            customFn: {
                type: Function,
                default: () => {}
            },
            autoClear: {
                type: Boolean,
                default: true
            },
            notEmpty: {
                type: Boolean,
                default: false
            },
            //需要显示的图片链接
            imgShowList: {
                type: Array,
                // default: () => ["static/image/demo1.png", "static/image/demo2.png"]
                default: () => []
            },
            maxCount: {
                type: Number,
                default: 1
            },
            //删除图片方法后执行的回调
            deleteCallback: {
                type: Function,
                default: () => {}
            },
            //quality:根据质量来压缩，size：根据尺寸来压缩
            compressStrategy: {
                type: String,
                default: "quality"
            },
            maxCompressWidth: {
                type: Number,
                default: 150
            },
            maxCompressHeight: {
                type: Number,
                default: 150
            },
            
		},
		data () {
			return {
                fileArray: [],
                uploadArray: [],
                result: null,
                longPressTimer: null,
                longPressTime: 1000,
                eventUtils: null,
                shortClickTime: 300,//用户做一次点击操作所允许的最大值，单位毫秒
                slideDistance: 30,//用户做一次点击操作所允许滑动的最大距离，单位px,
                maxSize: 2 * 1024 * 1024,//图片超过2MB就进行压缩处理
//              maxCompressWidth: 150,
//              maxCompressHeight: 150,
                coverSrc: "",
                coverShow: false,
                context: "",//canvas绘制上下文,
				maxWidth: 1000,//canvas允许绘制的最大宽度
                maxHeight: 1000,//canvas允许绘制的最大高度,
                compressCoefficient: 0.4,//压缩系数,
                // firstIn: true
                //读取本地图片过程中的进度
                process: 0,
                processTitle: "读取本地文件……",
                imgShowListStates: {},//用来管理回显的图片的状态
			}
		},
		computed: {
            pageHeight() {
                return window.screen.height;
            },
            pageWidth() {
                return window.screen.width;
            },
            getFileArray() {
                return this.fileArray;
            }
		},
		methods: {
            //使用单例模式创建一个FileReader对象
            getFileReaderSingle(fn) {
                return () => {
                    return this.result || (this.result = fn());
                }
            },
            //创建一个FileReader对象
            createFileReader() {
                console.log("单例模式，只调用一次new FileReader");
                return new FileReader();
            },
            //根据图片尺寸来判断是否需要压缩
            judgeImgNeedCompressBySize(src) {
                return new Promise((resolve, reject) => {
                    let img = new Image();
                    img.onload = () => {
                        console.log("拿到图片宽高", img.width, img.height);

                        resolve(true);
                    }
                    img.onerror = () => {
                        resolve(false);
                    }
                    img.src = src;
                });
                
            },
            //根据图片质量判断是否需要压缩
            judgeImgNeedCompressByQuality(size) {
                return size > this.maxSize;
            },
            //选择图片
            chooseImg(event) {
                // console.log(event.target.files);
                if (event.target.files[0]) {
                    var reader = this.getFileReaderSingle(this.createFileReader)();
                    //读取过程中
                    // reader.onprogress = (event) => {
                    //     console.log("正在读取中", event);
                    // }
                    //成功读取
                    reader.onload = async (event2) => {
                        //是否需要质量压缩
                        if (this.compressStrategy === "quality" && this.judgeImgNeedCompressByQuality(event.target.files[0].size)) {
                            //开始进行压缩操作
                            // console.log("开始进行压缩处理");
                            this.compressImg(event2.target.result);
                        } 
                        //是否需要尺寸压缩
                        else if (this.compressStrategy === "size" && await this.judgeImgNeedCompressBySize(event2.target.result)) {
                            console.log("开始进行尺寸压缩");
                            this.compressImgBySize(event2.target.result);
                        }
                        //不压缩 
                        else {
                            //这个数组用于图片展示
                            this.fileArray.push(event2.target.result);
                            //这个数组用于存储上传的数据
                            this.uploadArray.push({url: event.target.files[0], type: 'upload'});
                        }

                    }
                    //读取失败
                    reader.onerror = () => {
                        //预览图片失败
                        this.failToast("图片选择失败");
                    }
                    reader.onloadend = () => {
                        //读取完成，无论成功还是失败
                        event.target.value = "";
                    }
                    reader.readAsDataURL(event.target.files[0]);
                }

            },
            //拿到当前暂存图片的img标签
            getTempImg() {
                return this.$refs.tempImg;
            },
            //拿到当前canvas
            getCanvas() {
                return this.$refs.canvas;
            },
            //设置canvas的宽高
            setCanvas(w, h) {
                this.getCanvas().width = w;
                this.getCanvas().height = h;
            },
            //清除画布上的内容
            clearCanvasContent(w, h) {
                //如果没有传参数，默认清空画布
                if (!w || !h) {
                    w = this.getCanvas().width;
                    h = this.getCanvas().height;
                }
                this.getContext().clearRect(0, 0, w, h);
            },
            //清除tempImg暂存的内容
            clearTempImgContent() {
                this.getTempImg().src = "";
            },
            //开始进行压缩处理，接收FileReader读取生成的URL
            //根据尺寸来压缩
            compressImgBySize(src) {
                this.getTempImg().onload = () => {
                    //图片加载完毕，进行canvas绘制
                    console.log("图片加载完毕，进行canvas绘制");
                    let context = this.getContext();
                    // let callback = () => {
                        //设置画布大小
                        this.setCanvas(this.maxCompressWidth, this.maxCompressHeight);
                        //开始canvas绘制
                        context.drawImage(this.getTempImg(), 0, 0, this.maxCompressWidth, this.maxCompressHeight);
                        //绘制完毕后拿到生成的url，压缩指数为0.4
                        let compressSrc = this.getCanvas().toDataURL("image/jpeg");
                        //压缩后的url放到预览数组里
                        this.fileArray.push(compressSrc);
                        //将压缩后的url进行二进制转码，放到uploadArray（上传数组）里
                        this.uploadArray.push({url: this.dataURLtoBlob(compressSrc), type: 'upload'});
                        console.log("拿到转换后的blob", this.dataURLtoBlob(compressSrc));
                        //进行清空操作
                        this.clearCanvasContent();
                        this.clearTempImgContent();
                    // }
                    // this.getCompressTargetSize(src, callback);
                }
                this.getTempImg().src = src;
            },
            //开始进行压缩处理，接收FileReader读取生成的URL
            //根据质量来压缩
            compressImg(src) {
                console.log("开始进行压缩处理");
                //使用暂存Img标签显示出图片
                this.getTempImg().onload = () => {
                    //图片加载完毕，进行canvas绘制
                    console.log("图片加载完毕，进行canvas绘制");
                    let context = this.getContext();
                    let callback = (w, h) => {
                        //拿到计算后的宽高
                        console.log("拿到计算后的宽高", w, h);
                        //设置画布大小
                        this.setCanvas(w, h);
                        //开始canvas绘制
                        context.drawImage(this.getTempImg(), 0, 0, w, h);
                        //绘制完毕后拿到生成的url，压缩指数为0.4
                        let compressSrc = this.getCanvas().toDataURL("image/jpeg", this.compressCoefficient);
                        //压缩后的url放到预览数组里
                        this.fileArray.push(compressSrc);
                        //将压缩后的url进行二进制转码，放到uploadArray（上传数组）里
                        this.uploadArray.push({url: this.dataURLtoBlob(compressSrc), type: 'upload'});
                        console.log("拿到转换后的blob", this.dataURLtoBlob(compressSrc));
                        //进行清空操作
                        this.clearCanvasContent();
                        this.clearTempImgContent();
                    }
                    this.getCompressTargetSize(src, callback);
                }
                console.log("图片暂存标签拿到src");
                this.getTempImg().src = src;
            },
            //以单例模式获取canvas绘制上下文
            getContext() {
                if (this.context) {
                    return this.context;
                } else {
                    return this.getCanvas().getContext("2d");
                }
            },
            //获取一张图片原始的宽高
            getImgOriginWidthAndHeight(src) {
                return new Promise(resolve => {
                    let img = new Image();
                    img.onload = () => {
                        resolve({
                            width: img.width,
                            height: img.height
                        });
                    };
                    img.src = src;
                });
                
            },
            //根据图片的原始大小进行按比例绘制
            async getCompressTargetSize(src, callback) {
                let originWidthandHeight = await this.getImgOriginWidthAndHeight(src);
                if (callback) {
                    let width = originWidthandHeight.width;
                    let height = originWidthandHeight.height;
                    let paintWidth = width;//绘制的宽度
                    let paintHeight = height;//绘制的高度
                    if (width >= height && width > this.maxWidth) {
                        //如果图片宽大于最大宽度，则进行宽高等比例缩放
                        paintWidth = this.maxWidth;
                        paintHeight = (height / width) * paintWidth;

                    } else if (height > width && height > this.maxHeight) {
                        //如果图片高大于最大高度，则进行宽高等比例缩放
                        paintHeight = this.maxHeight;
                        paintWidth = (width / height) * paintHeight;
                    }
                    callback(paintWidth, paintHeight);
                }
            },
            //base64转blob二进制
            dataURLtoBlob(dataurl) {
                var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
                    bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
                while(n--){
                    u8arr[n] = bstr.charCodeAt(n);
                }
                return new Blob([u8arr], {type:mime});
            },
            //删除选中的图片
            deleteImg(index) {
            	console.log(index,"4444444444")
                if (index == undefined) {
                    this.fileArray = [];
                    this.uploadArray = [];
                    // this.deleteCallbackEvent();
                    return;
                }
                this.fileArray.splice(index, 1);
                this.uploadArray.splice(index, 1);
                 //this.deleteCallbackEvent(index);
                
                 //用户自定义的删除事件
                this.deleteCallback();
            },
            //当用户点击删除图片的时候，把回显的图片也删除掉
            deleteCallbackEvent(index) {
                if (index) {
                    this.imgShowListStates[index] = {
                        state: false
                    }
                } else {
                    this.imgShowList.forEach((item, index) => {
                        this.imgShowListStates[index] = {
                            state: false
                        }
                    });
                }
                //用户自定义的删除事件
                this.deleteCallback();
            },
            //上传所选图片
            upload() {
                if (this.loading) {
                    showLoading();
                }
                //这里依据上传的数组进行判断，因为可能有回显的图片
                let uploadArray = this.uploadArray.filter(item => {
                    return item.type;
                }).map(item => {
                    return item.url;
                });
                //如果没有图片上传，则直接返回一个Promise对象，表示没上传，返回status：2
                if (!uploadArray.length) {
                    hideLoading();
                    return new Promise(resolve => {
                        let obj = {
                            status: 2,
                            data: [],
                            msg: "没有图片上传"
                        }
                        resolve(obj);
                    });
                }
                return new Promise(async (resolve, reject) => {
                    let result = await uploadImg(uploadArray);
                    for (let i = 0; i < uploadArray.length; i++) {
                        !result.size && (result.size = []);
                        let _data = await this.getImgOriginWidthAndHeight(result.data[i]);
                        result.size[i] = {width: _data.width, height: _data.height};
                    }
                    hideLoading();
                    console.log("result", result);
                    resolve(result);
                });
            },
            async mUpload() {
                let params = await this.upload();
                console.log(params);
            },
            //自定义touch事件，模拟长按和点击
            touchStartEvent(event, index) {
                this.longPressTimer = setTimeout(() => {
                    console.log(`第${index}个长按事件触发`);
                    MessageBox.confirm('要删除这张图片吗？').then(action => {
                        //确定事件
                        this.deleteImg(index);
                    }, cancel => {
                        //取消删除
                    });
                    this.clearLongPressTimer();
                }, this.longPressTime);
                //定义一个时间戳，代表用户按下手指的起始时间
                this.startTime = new Date().getTime();
                //定义一个对象，代表用户按下的手指位置
                // console.log(event);
                this.startPos = {
                    posX: event.touches[0].clientX,
                    posY: event.touches[0].clientY
                }
            },
            touchMoveEvent(event) {
                this.clearLongPressTimer();
            },
            touchEndEvent(event, index) {
                this.clearLongPressTimer();
                //如果用户手指抬起的结束时间小于this.shortClickTime并且滑动距离不大于this.slideDistance
                //可以认为用户做了一次点击事件
                let endPos = {
                    posX: event.changedTouches[0].clientX,
                    posY: event.changedTouches[0].clientY
                }
                let endTime = new Date().getTime();
                if (endTime - this.startTime < this.shortClickTime && Math.abs(endPos.posX - this.startPos.posX) < this.slideDistance && Math.abs(endPos.posY - this.startPos.posY) < this.slideDistance) {
                    console.log("用户触发了点击事件");
                    //弹出一个遮罩层，显示用户点击的图片大图
                    // setTimeout(() => {
                        this.showCover(index);
                    // }, 150);

                }
                //做一下清理操作
                this.startPos = null;
                this.startTime = null;
            },
            //清除计时器
            clearLongPressTimer() {
                clearTimeout(this.longPressTimer);
                this.longPressTimer = null;
            },
            //显示成功Toast
            successToast(msg) {
                Toast({
                    duration: 1000,
                    message: msg,
                    iconClass: "aui-iconfont aui-icon-correct"
                });
            },
            //显示失败Toast
            failToast(msg) {
                Toast({
                    duration: 1000,
                    message: msg,
                    iconClass: "aui-iconfont aui-icon-close"
                });
            },
            //显示遮罩层
            showCover(index) {
                setTimeout(() => {
                    this.coverShow = true;
                    this.coverSrc = this.fileArray[index];
                    document.body.appendChild(this.$refs.gwImgCover);
                }, 400);
            },
            //隐藏遮罩层
            hideCover() {
                setTimeout(() => {
                    this.coverShow = false;
                    this.coverSrc = "";
                }, 300);

            },
            hideCoverBeforeDestroy() {
                this.coverShow = false;
                this.coverSrc = "";
                this.$refs.gwImgCover.style.display = "none";
            }
        },
        created () {
            setTimeout(() => {
                this.$refs.canvas.width = 1000;
                this.$refs.canvas.height = 1000;
            }, 500);
            this.fileArray = [...this.imgShowList];
            this.uploadArray = [...this.imgShowList];
        },
        mounted () {
        },
        beforeDestroy() {
            this.hideCoverBeforeDestroy();
        },
        watch: {
            imgShowList(newVal, oldVal) {
                if (newVal.length && newVal.join(",") !== oldVal.join(",")) {

                    console.log("imgShowList发生变化", newVal);
                    //这里每次变化的时候要进行状态判定
                    this.fileArray = [...this.imgShowList];
                    this.uploadArray = [...this.imgShowList];

                }
            }
        }

	}
</script>

<style scoped>
    .imgUploadBox {
        display: flex;
        padding: 10px;
        box-sizing: border-box;
        flex-flow: row wrap;
        position: relative;
    }
    .imgItem {
        width: 120px;
        padding-bottom: 120px;
        margin: 2.5px;
        height: 0;
        position: relative;
        /* overflow: hidden; */
    }
    .upload-btn {
        position: relative;
        overflow: hidden;
        height: 120px;
        width: 120px;
        margin: 2.5px;
        border: 2px dashed #d4d4d1;
    }
    .upload-btn .hengxian {
        display: block;
        background: #d4d4d1;
        width: 60px;
        height: 3px;
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        margin: auto;
    }
    .upload-btn .shuxian {
        display: block;
        background: #d4d4d1;
        width: 3px;
        height: 60px;
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        margin: auto;
    }
    .upload-btn input {
        position: absolute;
        top:0;
        left:0;
        display: block;
        width: 100%;
        height: 100%;
        opacity: 0;
    }
    .aui-row-padded {
        margin: 0;
    }
    .gw-img-cover {
        position: fixed;
        left: 0;
        top: 0;
        z-index: 99999;
        width: 100vw;
        height: 100vh;
    }
    .gw-img-cover .cover {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        background: #000;
        opacity: 0.6;
    }
    .gw-img-cover img {
        position: absolute;
        left: 0;
        right: 0;
        bottom: 0;
        top: 0;
        margin: auto;
    }
    .canvasBox {
        width: 1px;
        height: 1px;
        overflow: hidden;
    }
    /* 删除按钮的样式 */
    .delete-btn {
        background-color: #ef8a80;
        border-radius: 50%;
        color: #fff;
        width: 22px;
        height: 22px;
        /* line-height: 26px; */
        font-weight: bold;
        border: 1px solid #e74c3c;
        font-size: 20px;
        position: absolute;
        right: -8px;
        top: -8px;
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
    }
    .delete-btn:hover {
        background-color: #e74c3c;
        border-color: #9c3428;
    }
</style>


